let appIcon = this._items[this._selectedIndex];
if (this._currentWindow < 0)
appIcon.app.activate_window(appIcon.cachedWindows[0], timestamp);
- else
+ else if (appIcon.cachedWindows[this._currentWindow])
Main.activateWindow(appIcon.cachedWindows[this._currentWindow], timestamp);
this.parent();
})
});
this._thumbnails = null;
- this._switcherList._items[this._selectedIndex].remove_accessible_state (Atk.StateType.EXPANDED);
+ if (this._switcherList._items[this._selectedIndex])
+ this._switcherList._items[this._selectedIndex].remove_accessible_state (Atk.StateType.EXPANDED);
},
_createThumbnails : function() {
this._thumbnails = new ThumbnailList (this._items[this._selectedIndex].cachedWindows);
this._thumbnails.connect('item-activated', Lang.bind(this, this._windowActivated));
this._thumbnails.connect('item-entered', Lang.bind(this, this._windowEntered));
+ this._thumbnails.actor.connect('destroy', () => {
+ this._thumbnails = null;
+ this._thumbnailsFocused = false;
+ });
this.actor.add_actor(this._thumbnails.actor);
_onDestroy: function() {
if (this._mouseTimeOutId != 0)
Mainloop.source_remove(this._mouseTimeOutId);
+
+ this.icons.forEach(icon => {
+ icon.app.disconnect(icon._stateChangedId);
+ });
},
_setIconSize: function() {
// show a dim arrow, but show a bright arrow when they are
// highlighted.
highlight : function(n, justOutline) {
- if (this._curApp != -1) {
+ if (this.icons[this._curApp]) {
if (this.icons[this._curApp].cachedWindows.length == 1)
this._arrows[this._curApp].hide();
else
this.icons.push(appIcon);
let item = this.addItem(appIcon.actor, appIcon.label);
+ appIcon._stateChangedId = appIcon.app.connect('notify::state', app => {
+ if (app.state != Shell.AppState.RUNNING)
+ this._removeIcon(app);
+ });
+
let n = this._arrows.length;
let arrow = new St.DrawingArea({ style_class: 'switcher-arrow' });
arrow.connect('repaint', function() { SwitcherPopup.drawArrow(arrow, St.Side.BOTTOM); });
arrow.hide();
else
item.add_accessible_state (Atk.StateType.EXPANDABLE);
- }
+ },
+
+ _removeIcon: function(app) {
+ let index = this.icons.findIndex(icon => {
+ return icon.app == app;
+ });
+ if (index === -1)
+ return;
+
+ this.icons.splice(index, 1);
+ this.removeItem(index);
+
+ if (this._curApp == index)
+ this._curApp = SwitcherPopup.mod(index, this.icons.length);
+ if (this.icons.length > 0)
+ this.highlight(this._curApp);
+ else
+ this.actor.destroy();
+ },
});
var ThumbnailList = new Lang.Class({
}
}
+
+ this.actor.connect('destroy', this._onDestroy.bind(this));
},
addClones : function (availHeight) {
let clone = _createWindowClone(mutterWindow, thumbnailSize);
this._thumbnailBins[i].set_height(binHeight);
this._thumbnailBins[i].add_actor(clone);
+
+ clone._destroyId = mutterWindow.connect('destroy', Lang.bind(this, this._removeThumbnail, clone));
this._clones.push(clone);
}
// Make sure we only do this once
this._thumbnailBins = new Array();
- }
+ },
+
+ _removeThumbnail: function(source, clone) {
+ let index = this._clones.indexOf(clone);
+ if (index === -1)
+ return;
+
+ this._clones.splice(index, 1);
+ this._windows.splice(index, 1);
+ this._labels.splice(index, 1);
+ this.removeItem(index);
+
+ if (this._clones.length > 0)
+ this.highlight(SwitcherPopup.mod(index, this._clones.length));
+ else
+ this.actor.destroy();
+ },
+
+ _onDestroy: function() {
+ this._clones.forEach(clone => {
+ if (clone.source)
+ clone.source.disconnect(clone._destroyId);
+ });
+ },
+
});
var WindowIcon = new Lang.Class({